#[derive(Debug, Clone)]
struct Point2D {
    x: f64,
    y: f64,
}

#[derive(Debug, Clone)]
struct Point3D {
    x: f64,
    y: f64,
    z: f64,
}

// impl Into<Point3D> for Point2D {
//     fn into(self) -> Point3D {
//         Point3D {
//             x: self.x,
//             y: self.y,
//             z: 0.0,
//         }
//     }
// }

impl From<Point2D> for Point3D {
    fn from(p: Point2D) -> Self {
        Point3D {
            x: p.x,
            y: p.y,
            z: 0.0,
        }
    }
}

/// from函数会消耗传入的值
/// 实现了from方法, 在into的时候需要指定类型
fn main() {
    let p2d = Point2D { x: 1.0, y: 2.0 };
    let p3d1: Point3D = p2d.into(); // p2d实例调用into方法，返回Point3D实例
    let p3d2_1 = Into::<Point3D>::into(p2d.clone()); // Into trait的into方法，返回Point3D实例
    let p3d2_2: Point3D = Into::into(p2d.clone()); // Into trait的into方法，返回Point3D实例
    let p3d2_3 = Into::<Point3D>::into(p2d.clone());
    let p3d3 = Point3D::from(p2d.clone()); // 调用关联函数from
    let p3d4 = <Point3D as From<Point2D>>::from(p2d.clone()); // 上面的完整版本
    let p3d5: Point3D = Point2D::into(p2d.clone()); // Point2D的关联函数是推导出的, 无法使用具体类型参数
    let p3d6 = <Point2D as Into<Point3D>>::into(p2d.clone()); // 上面的完整版本
    let p3d7: Point3D = From::from(p2d.clone()); // 调用From trait的from方法，返回Point3D实例
    let p3d8 = <Point3D as From<Point2D>>::from(p2d.clone()); // ; // 上面的完整版本
    println!("p2d = ({}, {})", p2d.x, p2d.y);
    println!("p3d1 = ({}, {}, {})", p3d1.x, p3d1.y, p3d1.z);
    println!("p3d2_1 = ({}, {}, {})", p3d2_1.x, p3d2_1.y, p3d2_1.z);
    println!("p3d2_2 = ({}, {}, {})", p3d2_2.x, p3d2_2.y, p3d2_2.z);
    println!("p3d2_3 = ({}, {}, {})", p3d2_3.x, p3d2_3.y, p3d2_3.z);
    println!("p3d3 = ({}, {}, {})", p3d3.x, p3d3.y, p3d3.z);
    println!("p3d4 = ({}, {}, {})", p3d4.x, p3d4.y, p3d4.z);
    println!("p3d5 = ({}, {}, {})", p3d5.x, p3d5.y, p3d5.z);
    println!("p3d6 = ({}, {}, {})", p3d6.x, p3d6.y, p3d6.z);
}
